package org.neptune.web.controller;

import java.io.IOException;

import javax.security.sasl.AuthenticationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.neptune.api.entity.AesKeyBean;
import org.neptune.api.entity.Seckill;
import org.neptune.api.request.LoginRequest;
import org.neptune.common.constant.NeptuneConstant;
import org.neptune.common.response.ResponseBean;
import org.neptune.common.util.RandomUtils;
import org.neptune.service.config.NeptuneConfig;
import org.neptune.service.redis.RedisRepository;
import org.neptune.service.redis.RedissonUtil;
import org.neptune.service.service.CaptchaService;
import org.neptune.service.service.IndexService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

/**
 * @author lwl
 * @date 2019/8/14 17:25
 */
@Controller
public class IndexController {

	private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

	@Autowired
	private RedisRepository redisRepository;

	@Autowired
	private NeptuneConfig neptuneConfig;

	@Autowired
	private IndexService indexService;

	@Autowired
	private CaptchaService captchaService;

	@Autowired
	private RestTemplate restTemplate;

	@RequestMapping("/")
	public String homePage() {

		return "/home/index";
	}

	/**
	 * 登录首页
	 * 
	 * @param map
	 * @return
	 */
	@RequestMapping("/login")
	public String index(ModelMap map) {

		String token = RandomUtils.createRandomUUID();
		String aesKey = RandomUtils.get16Str();
		String offset = RandomUtils.get16Str();
		// 密码加密临时秘钥
		AesKeyBean aesKeyBean = new AesKeyBean(token, aesKey, offset);

		redisRepository.set(RedissonUtil.getRedisKey(NeptuneConstant.REDIS_RSAKEY_SESSION, token),
				aesKeyBean, neptuneConfig.loginSessionCachetime);

		map.addAttribute("token", token);
		map.addAttribute("aesKey", aesKey);
		map.addAttribute("offset", offset);
		map.addAttribute("isNeedCaptcha", neptuneConfig.needCaptcha);

		return "/login/index";
	}

	/**
	 * 登录校验
	 * 
	 * @param loginRequest
	 * @return
	 */
	@RequestMapping("/loginVerify")
	@ResponseBody
	public ResponseBean<Object> loginVerify(LoginRequest loginRequest) {

		// 图片验证码
		if (StringUtils.equals(NeptuneConstant.COMMON_TRUE, neptuneConfig.needCaptcha)){
			if (!captchaService.verifyImageCode(loginRequest)){
				return ResponseBean.fail(null, "验证码验证失败");
			}
		}
		try{
			return indexService.loginVerify(loginRequest);
		} catch (UnknownAccountException uae){
			logger.warn("用户帐号不正确");
		} catch (IncorrectCredentialsException ice){
			logger.warn("用户密码不正确");
		} catch (LockedAccountException lae){
			logger.warn("用户帐号被锁定");
		} catch (AuthenticationException ae){
			logger.warn("登录出错");
		} catch (Exception ae){
			logger.warn("登录出错");
		}
		return ResponseBean.fail(null, "登录失败");
	}

	/**
	 * 退出
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping("/loginout")
	public void loginout(HttpServletRequest request, HttpServletResponse response) {

		try{
			Subject subject = SecurityUtils.getSubject();
			if (subject.isAuthenticated()){
				subject.logout();
			}
			response.sendRedirect(request.getContextPath() + "/login");
		} catch (IOException e){
			logger.error("login out error : ", e);
		}
	}

	/**
	 * 注册
	 * 
	 * @param map
	 * @return
	 */
	@RequestMapping("/registerIndex")
	public String registerIndex(ModelMap map) {

		String token = RandomUtils.createRandomUUID();
		String aesKey = RandomUtils.get16Str();
		String offset = RandomUtils.get16Str();
		// 密码加密临时秘钥
		AesKeyBean aesKeyBean = new AesKeyBean(token, aesKey, offset);
		redisRepository.set(RedissonUtil.getRedisKey(NeptuneConstant.REDIS_RSAKEY_SESSION, token),
				aesKeyBean, neptuneConfig.loginSessionCachetime);

		map.addAttribute("token", token);
		map.addAttribute("aesKey", aesKey);
		map.addAttribute("offset", offset);
		return "/register/index";
	}

	@RequestMapping("/seckill/index")
	public String seckillIndex() {

		return "/seckillGoods/index";
	}

	@RequestMapping("/home/index")
	public String homeIndex() {

		return "/home/index";
	}

	@RequestMapping("/seckillDetail/index")
	public String seckillDetailIndex(ModelMap map, String seckillGoodsId) {
		this.convertInfo(map, seckillGoodsId);
		return "/seckillDetail/index";
	}

	@RequestMapping("/seckillLog/index")
	public String seckillLogIndex() {

		return "/seckillLog/index";
	}

	@RequestMapping("/seckillOrder/index")
	public String seckillOrderIndex() {

		return "/seckillOrder/index";
	}

	private void convertInfo(ModelMap map, String seckillGoodsId) {
		String countKey = RedissonUtil.getRedisKey(NeptuneConstant.REDIS_SECKILL_GOODS_COUNT,
				seckillGoodsId);
		String infoKey = RedissonUtil.getRedisKey(NeptuneConstant.REDIS_SECKILL_GOODS_INFO,
				seckillGoodsId);
		long count = redisRepository.getLong(countKey);
		Seckill seckill = redisRepository.get(infoKey, Seckill.class);
		map.put("seckillGoodsCount", count);
		map.put("seckillGoodsName", "");
		map.put("seckillGoodsId", "");
		if (seckill != null){
			map.put("seckillGoodsName", seckill.getName());
			map.put("seckillGoodsId", seckill.getSeckillId());
		}
	}

	/**
	 * 获取天气接口 不另添加文件了
	 * 
	 * @return
	 */
	@RequestMapping("/queryWeather")
	@ResponseBody
	public ResponseBean<Object> quconeryWeather() {

		StringBuilder builder = new StringBuilder();
		builder.append(neptuneConfig.weatherPath);
		builder.append("?");
		builder.append("appid=").append(neptuneConfig.weatherAppid);
		builder.append("&appsecret=").append(neptuneConfig.weatherAppsercet);
		builder.append("&version=").append(neptuneConfig.weatherVersion);

		Object result = restTemplate.getForObject(builder.toString(), Object.class);

		return ResponseBean.success(result);
	}

}
